Markdown上代码高亮,最开始打算用SyntaxHighlighter(为了跟之前保持一致),折腾了一段时间,发现有个问题很难逾越:SyntaxHighlighter要求<pre>...</pre>
间的代码,所有左尖括号<
必须全部转化成HTML实体<
,详情见博文《在Markdown使用代码高亮SyntaxHighlighter》。所以决定寻找另一款代码高亮,最后选择Google Code Prettify
,因为StackOverflow和Google Code也用这个货,除此之外,Google Code Prettify
还有一个很酷的特性,可以启发式识别语言。本文分享如何安装Google Code Prettify
并介绍如何使其与SyntaxHighlighter兼容。
1. 无插件安装Google Code Prettify
步骤1:下载和定制
在Google Code Prettify官网下载prettify-small-4-Mar-2013.tar.bz2
,放到主题或子主题目录下。另,Google Code Prettify已经移到了GitHub,在这里。
目前官方只提供5种主题样式,在这里预览效果,下载自己喜欢的主题样式(在prettify-4-Mar-2013.tar.bz2
下的styles/
),并放到上述的google-code-prettify/
目录下。也可以找个第三方提供的主题样式,比如这里。
步骤2:加载js和css
在functions.php
添加必备css样式和js脚本,源代码如下(选个自己喜欢的主题):
function add_google_code_prettify_scripts() {
wp_enqueue_style( 'prettify.css', get_stylesheet_directory_uri() . '/google-code-prettify/prettify.css' );
wp_enqueue_style( 'sons-of-obsidian.css', get_stylesheet_directory_uri() . '/google-code-prettify/sons-of-obsidian.css' );
wp_enqueue_script( 'prettify.js', get_stylesheet_directory_uri() . '/google-code-prettify/prettify.js', array(), false, false);
}
add_action( 'wp_enqueue_scripts', 'add_google_code_prettify_scripts' );
我的google-code-prettify
是在子主题,使用get_stylesheet_directory_uri()
获取当前目录,如果是放在主题,则使用get_template_directory_uri()
。
步骤3:启用Google Code Prettify
在footer.php
中</body>
前加入如下代码就能实现代码高亮了。
<script>
jQuery(document).ready(function () {
jQuery("pre").addClass("prettyprint linenums");
prettyPrint();
});
</script>
在我的例子种,如果用$
代替jQuery
会提示Uncaught TypeError: $ is not a function
错误。
2. 与SyntaxHighlighter兼容或取代
在Markdown使用triple backticks插入代码块会被解析成<pre><code class="...">...</code></pre>
,这里<pre>...</pre>
会被SyntaxHighlighter处理,而
<code class="...">...</code>
跟`...`
冲突(我还自定义了样式),所以如果只是按上述步骤3简单加载Google Code Prettify,新插入的代码会高亮得一塌糊涂,更别说SyntaxHighlighter要求所有<
需要转换成<
)。
有个解决办法很容易想到,那就是将<pre><code class="...">...</code></pre>
转化成<pre class="...">...</pre>
,以下是实现该功能的源代码(得益于@powerxing的指点):
<script>
jQuery(document).ready(function(){
jQuery('pre').each(function(){
var el = jQuery(this).find('code');
var code_block = el.html(); // remove the pairwise tag of <code></code>
var lang = el.attr('class');
if (el.length > 0) { // <pre>...</pre> with <code>...</code> inside
if (lang) {
jQuery(this).addClass('prettyprint linenums lang-' + lang).html(code_block);
} else {
jQuery(this).addClass('prettyprint linenums').html(code_block);
}
} else { // <pre>...</pre> without <code>...</code> inside
jQuery(this).removeClass().addClass('prettyprint linenums'); // take over SyntaxHighlighter
}
});
});
</script>
事实上,上述代码让Google Code Prettify彻底代替了SyntaxHighlighter,见这一行jQuery(this).removeClass().addClass('prettyprint linenums');
,这样整个网站的代码风格再次统一了。
如果triple backticks后没有声明语言,不用担心,Google Code Prettify的启发式算法会自己判段。Google Code Prettify默认支持的语言后缀lang-*
有:
"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
"java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
"xhtml", "xml", "xsl"
至此,可以自豪地在Markdown插入代码块了。